package cn.mill.support;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.mill.common.Context;
import cn.mill.common.HttpMethod;
import cn.mill.common.Protocol;
import cn.mill.common.Tag;
import cn.mill.common.annotation.HttpDefine;
import cn.mill.common.annotation.SPI;
import cn.mill.common.data.Item;
import cn.mill.common.message.Message;
import cn.mill.core.DefaultMessage;
import cn.mill.core.utils.NormUtil;
import cn.mill.support.http.HttpHandler;

@SPI("http")
public class HttpProtocol implements Protocol<String, InputStream> {
	private static Logger logger = LoggerFactory.getLogger(HttpProtocol.class);
	
	@Override
	public Message<InputStream> invoker(Context invoke, Message<String> inputMessage) {
		DefaultMessage<InputStream> message = new DefaultMessage<InputStream>();
		
		String url = NormUtil.getUri(invoke.getNode(), invoke.getMapping());
		HttpDefine httpDefine = invoke.getMethod().getAnnotation(HttpDefine.class);
		
		List<Header> headers = new ArrayList<Header>();
		Iterator<Map.Entry<String, Item>> iterator = invoke.getAttachments().entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, Item> entry = iterator.next();
			if (entry != null) {
				Item i = entry.getValue();
				if (i.getProperty() != null && Tag.HEADER.equals(i.getProperty().tag())) {
					headers.add(new BasicHeader(i.getName(), (String) i.getValue()));
				}
			}
		}
		
		InputStream in = null;
		try {
			if (httpDefine != null && HttpMethod.GET.equals(httpDefine.method())) {
				in = HttpHandler.get(url, headers.toArray(new Header[headers.size()]), 0, 0);
			} else {
				in = HttpHandler.post(url, headers.toArray(new Header[headers.size()]), inputMessage.getDataBlock(), 0, 0, true);
			}
		} catch (Exception e) {
			logger.error("HttpProtocol ", e);
			return message;
		}
		message.setDataBlock(in);
		logger.debug("url:[" + url + "]");
		return message;
	}
	
}
